﻿using Common.Helpers;
using MasterEntities.Abstraction;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DataAccessLayer.Helper
{
    public abstract class CommandGenerationBehaviour : ICommandTextGenerator
    {
        public IDomainObject m_InputObject;
        public IDomainObject m_BaseObject;
        public string[] derivedCommInput;
        public string[] baseCommInput;

        public Dictionary<int, string> GetCommandText(MasterEntities.Abstraction.IDomainObject obj)
        {
            m_InputObject = obj;             

            string baseClassCommand = string.Empty;
            if (!string.IsNullOrEmpty(obj.BaseClassName()))
            {
                m_BaseObject = MappBaseObjectProperties(obj);

                if (m_BaseObject != null && GlobalVariables.Instance.dbConnection == Common.Helpers.Enums.DatabaseConnection.MasterApp1)
                {
                    baseCommInput = SetBaseCommandParameters();
                    baseClassCommand = GetSpecializedCommandText(baseCommInput);
                }
            }
            derivedCommInput = SetDerivedCommandParameters();

            string derivedComm = GetSpecializedCommandText(derivedCommInput);

            return PopulateDictionaryCommandText(baseClassCommand, derivedComm);
        }

        public abstract string[] SetBaseCommandParameters();

        public abstract string[] SetDerivedCommandParameters();

        /// <summary>
        /// Override for DeleteCommand
        /// </summary>
        /// <param name="baseClassCommand"></param>
        /// <param name="derivedComm"></param>
        /// <returns>Dictionary</returns>
        public virtual Dictionary<int, string> PopulateDictionaryCommandText(string baseClassCommand, string derivedComm)
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();

            if (!string.IsNullOrEmpty(baseClassCommand))
                dict.Add(1, baseClassCommand);
            else
                dict.Add(1, derivedComm);

            if (!string.IsNullOrEmpty(baseClassCommand))
                dict.Add(2, derivedComm);

            return dict;
        }

        public abstract string GetSpecializedCommandText(params string[] input);
               
        private IDomainObject MappBaseObjectProperties(IDomainObject objectToCreate)
        {
            if (objectToCreate == null)
                return null;

            PropertyInfo[] derivedObjectProperties = objectToCreate.GetType().GetProperties();
            PropertyInfo[] baseObjectProperties = derivedObjectProperties.Where(derived => objectToCreate.GetType().BaseType.GetProperties().Any(b => b.Name == derived.Name)).Select(f => f).ToArray();

            object[] ctor = baseObjectProperties.Select(bas => objectToCreate.GetType().GetProperty(bas.Name).GetValue(objectToCreate)).ToArray();

            return Activator.CreateInstance(objectToCreate.GetType().BaseType, ctor) as IDomainObject;
        }
    }
}
